package com.example.thread.runnable;

import com.example.thread.mapper.TestMapper;
import com.example.thread.pojo.Demo;
import com.example.thread.util.SpringContext;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class SaveRunnable implements Callable<Boolean> {

    private Logger logger = LoggerFactory.getLogger(getClass());

    // 子线程计数器
    private CountDownLatch latch;
    // 主线程计数器
    private CountDownLatch mainLatch;
    // 是否抛出异常
    private Boolean flag = false;
    // 是否需要回滚
    private AtomicBoolean atomicBoolean;

    private PlatformTransactionManager transactionManager;

    public SaveRunnable() {}

    public SaveRunnable(CountDownLatch latch,CountDownLatch mainLatch, AtomicBoolean atomicBoolean, PlatformTransactionManager transactionManager) {
        this.latch = latch;
        this.mainLatch = mainLatch;
        this.atomicBoolean = atomicBoolean;
        this.transactionManager = transactionManager;
    }

    public SaveRunnable(CountDownLatch latch,CountDownLatch mainLatch, Boolean flag, AtomicBoolean atomicBoolean, PlatformTransactionManager transactionManager) {
        this.latch = latch;
        this.mainLatch = mainLatch;
        this.flag = flag;
        this.atomicBoolean = atomicBoolean;
        this.transactionManager = transactionManager;
    }

    @Override
    public Boolean call() throws Exception {
        long start = System.currentTimeMillis();
        // 执行任务\
        task();
        long end = System.currentTimeMillis();
//        logger.info("{} == 总时长 : {}", Thread.currentThread().getName(), end - start);

        return null;
    }

    private void task() {

        //开启事务
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            for (int i = 0; i < 100000; i++) {
                Demo demo = new Demo();
                if (flag) {
                    demo = null;
                }
                demo.setName(Thread.currentThread().getName() + "-" + i);
                TestMapper mapper = SpringContext.getBean(TestMapper.class);
                mapper.save(demo);
            }
            // 执行完成添加逻辑 计数器 -1
            latch.countDown();
        } catch (Exception e) {
            e.printStackTrace();
            // 报错则通知所有事物回滚
            atomicBoolean.set(true);
            latch.countDown();
        }

        // 等待所有行程执行完成 有异常则 回滚  没有 则 提交
        try {
            mainLatch.await();
        } catch (InterruptedException e) {
//            logger.error(e.getMessage());
        }
        if (atomicBoolean.get()) {
            logger.info("{} : rollback", Thread.currentThread().getName());
            transactionManager.rollback(status);
        } else {
            logger.info("{} : commit", Thread.currentThread().getName());
            transactionManager.commit(status);
        }
    }
}
